package com.cqut.familiarity.controller;


import cn.hutool.core.lang.UUID;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cqut.familiarity.contanst.FamiliarityContanst;
import com.cqut.familiarity.entity.User;
import com.cqut.familiarity.entity.vo.userVO.UserInfo;
import com.cqut.familiarity.properties.WechatAuthProperites;
import com.cqut.familiarity.service.RedisService;
import com.cqut.familiarity.service.UserService;
import com.cqut.familiarity.utils.FamiliarityUtil;
import com.cqut.familiarity.utils.ResultEntity;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 登录控制器
 * </p>
 *
 * @author atao
 * @since 2021-05-22
 */


@Api(description = "登录管理")
@CrossOrigin
@RestController
@RequestMapping("/familiarity")
public class LoginController {

    @Autowired
    private UserService userService;

    @Autowired
    private RedisService redisService;


    @Autowired
    private WechatAuthProperites wechatAuthProperites;


    /**
     * 微信用户授权登录接口
     * @param userInfo
     * @return
     * @throws Exception
     */
    @ApiOperation(value = "微信授权登录")
    @PostMapping(value = "/login")
    public ResultEntity login(
            @ApiParam(name = "userInfo", value = "微信用户基本信息", required = true)
            @RequestBody UserInfo userInfo) throws Exception {
        // 1.开发者服务器 登录凭证校验接口 appId + appSecret + 接收小程序发送的code
        JSONObject SessionKeyOpenId = FamiliarityUtil.getSessionKeyOrOpenId(userInfo.getCode(),wechatAuthProperites.getSessionHost(),wechatAuthProperites.getAppId(),wechatAuthProperites.getSecret(),wechatAuthProperites.getGrantType());
        // 2.接收微信接口服务 获取返回的参数
        String openid = SessionKeyOpenId.get("openid", String.class);
        String sessionKey = SessionKeyOpenId.get("session_key", String.class);
        System.out.println(sessionKey+"==="+openid);
        // 3.用户非敏感信息：rawDat 签名：signature
        JSONObject rawDataJson = JSONUtil.parseObj(userInfo.getRawData());
        // 4.校验签名 小程序发送的签名signature与服务器端生成的签名signature2 = sha1(rawData + sessionKey)
//        String signature2 = DigestUtils.sha1Hex(userInfo.getRawData() + sessionKey);
//         if (!userInfo.getSignature().equals(signature2)) {
//           return ResultEntity.error().data("message","签名校验失败");
//        }
        // encrypteData比rowData多了appid和openid
        JSONObject info = FamiliarityUtil.getUserInfo(userInfo.getEncrypteData(),
                sessionKey, userInfo.getIv());
        // 5.根据返回的User实体类，判断用户是否是新用户，是的话，将用户信息存到数据库；不是的话，更新最新登录时间
        User user = userService.isExist(openid);
        // 6.uuid生成唯一key，用于维护微信小程序用户与服务端的会话（或者生成Token）
        String skey = UUID.randomUUID().toString();
        // 7.设置会话超时时间
        redisService.setRedisKeyValueWithTimeout(skey,sessionKey,10,TimeUnit.MINUTES);
        // 8.判断用户是否是新用户
        if (user == null) {
            // 用户信息入库
            String nickName = rawDataJson.get("nickName",String.class);
            String avatarUrl = rawDataJson.get("avatarUrl",String.class);
            String gender = rawDataJson.get("gender",String.class);
            String city = rawDataJson.get("city",String.class);
            String country = rawDataJson.get("country",String.class);
            String province = rawDataJson.get("province",String.class);
            // 新增用户到数据库
            User newUser = new User();
            newUser.setName(nickName);
            newUser.setGender(gender);
            newUser.setAvatar(avatarUrl);
            newUser.setAddress(country+province+city);
            newUser.setOpenId(openid);
            userService.save(newUser);
            QueryWrapper<User> wrapper = new QueryWrapper<>();
            wrapper.eq("open_id",openid);
            user = userService.getOne(wrapper);
        } else {
            // 已存在，更新用户登录时间
            user.setLastLoginTime(new Date());
            userService.updateById(user);
        }
        // 9.把新的skey返回给小程序
        return ResultEntity.ok().data("skey",skey).data("userInfo",user).data("message", FamiliarityContanst.LOGIN_SUCCESS);
    }


}

